//
// Created by Administrator on 2021/8/10.
//

#ifndef STRUCTVIEW_DATAVIEW_H
#define STRUCTVIEW_DATAVIEW_H

#include "ViewInterface.h"
#include <cstdint>
#include <type_traits>

namespace details {
    template<typename DataType, size_t MAX_LEN, DataType ...DATAS>
    class DataView : public ViewInterface {
    public:
        constexpr static uint32_t size = sizeof...(DATAS);
        static_assert(size <= MAX_LEN, "data of out boundary.");

        explicit DataView(DataType _ref[MAX_LEN], const char* _name) : ref{_ref}, name{_name} {}

        auto build() -> void override{}
        auto equal() -> bool override{return true;}

    private:
        DataType* ref;
        const char* name;
        constexpr static DataType data[size] {DATAS...};
    };
}

#define __new_data_view__(param_name, ...) \
new details::DataView<std::remove_pointer_t<std::decay_t<decltype(parent)>>, ArraySize(parent), __VA_ARGS__>(parent, TO_STRING(param_name))

#define __def_data_view__(param_name, ...)               \
[](auto&& parent) {                                      \
    return __new_data_view__(param_name, ##__VA_ARGS__); \
}(parent.param_name)

#define VData(param_name, ...) __append_view__(__def_data_view__(param_name, ##__VA_ARGS__))
#define VContainer(...) __VA_ARGS__

#endif //STRUCTVIEW_DATAVIEW_H
